// Tile and image widths for mouse event handling.
var TILE_WIDTH = 128;
var TILE_HEIGHT = 128;
var IMAGE_WIDTH = 896;
var IMAGE_HEIGHT = 768;

var NUM_X_TILES = IMAGE_WIDTH/TILE_WIDTH;
var NUM_Y_TILES = IMAGE_HEIGHT/TILE_HEIGHT;

var CONTAINER_MARGIN_X = 16;

var CONTAINER_MARGIN_Y = 159;
var VIEWPORT_WIDTH = 50;
var VIEWPORT_HEIGHT = 50;

var VIEWPORT_BORDER = 1;
var VIEWPORT_TAG_BORDER = 1;

var ENTRY_TAG_WIDTH = 300;
var ENTRY_TAG_HEIGHT = 280;

var entryMode = false;

var TILES = null;

var HAS_SUBMITTED_MOD = false;
var HAS_SUBMITTED_PIXEL = false;
var HAS_SUBMITTED_FCC = false;

// Set a variable to control how often the browser goes and gets
// a new set of tiles.
var TILE_REFRESH_INTERVAL_MS = 15000;
var LAST10_REFRESH_INTERVAL_MS = 5000;
var NUM_TILES_TO_REFRESH_PER_INTERVAL = 5;

// Fade delay quantum
var QUANTUM = 100;
var OPACITY = 10;

var reveal_firstName = "";
var reveal_lastName = "";
var reveal_email = "";
var reveal_zip = "";
var reveal_keepMeUpdated = false;

function log(message) {
	var logDiv = e("logContent");

	var para = document.createElement("p");

	para.appendChild(document.createTextNode(message));

	logDiv.appendChild(para);

	// Set the log content to scroll down as entries are added.
	// 20 seems to work here, it's arbitrary.
	document.getElementById("logContent").scrollTop += 20;
}

function logToggle() {
	var lc = e("logContent");

	//alert(e("logContent").offsetHeight);
	if (lc.offsetHeight == 200) {
		lc.style.height = "40px";
	}

	else {
		lc.style.height = "200px";
	}

}

// Shortcut for getElementById
function e(id) {
	return document.getElementById(id);
}

function isValidEmail(str) {

	//return (str.indexOf(".") > 2) && (str.indexOf("@") > 0);

	//log("Received email: " + str);

	// Ensure @ in the email address
	if (str.indexOf("@") > 0) {
		var ss = str.substring(str.indexOf("@")+1, str.length);
		//log("Domain section: " + ss);

		// Ensure . in the domain string
		if (ss.indexOf(".") > 0) {
			var ss2 = ss.substring(ss.indexOf(".")+1, ss.length)
			//log("Domain type: " + ss2);
			// Ensure domain type is 2 or more characters
			if (ss2.length > 1) {
				return true;
			}
		}
	}
	return false;
}

// Computes the remainder of a/b
function mod(a, b) {
	return (a - (Math.floor(a/b) * b));
}

/*
function getTiles() {
	var date = new Date();

	var dateStamp = date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate() + "_" + (date.getHours()) + "-" + date.getMinutes() + "-" + date.getSeconds();
	// Initialize the tile array only once.
	if (TILES == null) {
		TILES = {};
		for (var i=0; i < NUM_Y_TILES; i++) {
			TILES[i] = {};
		}
	}

	var startTime = new Date();

	for (var y=0; y < NUM_Y_TILES; y++) {
		for (var x=0; x < NUM_X_TILES; x++) {

			// Create the new image objects and set their src - this loads them into the browser.
			var img = new Image();
			img.src = "/tile/" + y + "_" + x + "/" + dateStamp;
			TILES[y][x] = img;
		}
	}
}
*/

function getDateStamp() {
	var date = new Date();
	return date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate() + "_" + (date.getHours()) + "-" + date.getMinutes() + "-" + date.getSeconds();
}

function refreshTile(x, y) {
		var tileX = Math.floor(x/TILE_WIDTH);
		var tileY = Math.floor(y/TILE_HEIGHT);

		var img = new Image();
		img.src = "/tile/" + tileY + "_" + tileX + "/" + getDateStamp();
		
		//log("Refreshing tile (" + tileY + ", " + tileX + ")");
		
		TILES[tileY][tileX] = img;

		// Replace image src attribute with the newly loaded src.
		e(tileY + "_" + tileX).src = TILES[tileY][tileX].src;
		//e(tileY + "_" + tileX).style.display = "block";

}

function refreshTiles() {

	var date = new Date();

	var dateStamp = date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate() + "_" + (date.getHours()) + "-" + date.getMinutes() + "-" + date.getSeconds();

	var didInitTiles = false;

	// Initialize the tile array only once.
	if (TILES == null) {
		TILES = {};
		for (var i=0; i < NUM_Y_TILES; i++) {
			TILES[i] = {};
		}
		didInitTiles = true;
	}



	//var startTime = new Date();


	if(!didInitTiles){
		//we will only refresh NUM_TILES_TO_REFRESH_PER_INTERVAL each time
		for (var i=0; i < NUM_TILES_TO_REFRESH_PER_INTERVAL; i++){
			var tileX = Math.floor(Math.random() * NUM_X_TILES);
			var tileY = Math.floor(Math.random() * NUM_Y_TILES);

			var img = new Image();
			img.src = "/tile/" + tileY + "_" + tileX + "/" + dateStamp;

			TILES[tileY][tileX] = img;

			// Replace image src attribute with the newly loaded src.
			e(tileY + "_" + tileX).src = TILES[tileY][tileX].src;
			//e(tileY + "_" + tileX).style.display = "block";

		}
	}
	else{
		for (var y=0; y < NUM_Y_TILES; y++) {
			for (var x=0; x < NUM_X_TILES; x++) {
				// Create the new image objects and set their src - this loads them into the browser.
				var img = new Image();
				img.src = "/tile/" + y + "_" + x + "/" + dateStamp;

				TILES[y][x] = img;
			}
		}

		for (var y=0; y < NUM_Y_TILES; y++) {
			for (var x=0; x < NUM_X_TILES; x++) {
				// Replace image src attribute with the newly loaded src.
				e(y + "_" + x).src = TILES[y][x].src;
				//e(y + "_" + x).style.display = "block";
			}
		}
	}
	setTimeout("refreshTiles()", TILE_REFRESH_INTERVAL_MS);

}

function setViewport(x, y) {
	//log("Setting viewport: (" + x + ", " + y + ")");

	// Account for viewport being close to the edge of the image container and constrain it
	// to stay within the container.
	// Be sure to account for borders on BOTH SIDES and viewport dimensions

	// Method 0: No edge detection:
	/*
	e("viewport").style.left = (x - (VIEWPORT_WIDTH/2) - VIEWPORT_BORDER) + "px"
	e("viewport").style.top = (y - (VIEWPORT_HEIGHT/2) - VIEWPORT_BORDER) + "px"
	*/

	// Method 1: Follow edges except for bottom right corner where the viewport would go off
	// both bottom and right sides.
	// In that case, simply fix it both viewport and viewContainer, cursor will continue to move
	// over them as normal and allow pixels to be selected.

	// Not on edge
	if (((x + e("viewport").offsetWidth - VIEWPORT_WIDTH/2 - 2*VIEWPORT_BORDER) < IMAGE_WIDTH) && (x - VIEWPORT_WIDTH/2 > 0)) {
		e("viewport").style.left = (x - (VIEWPORT_WIDTH/2) - VIEWPORT_BORDER) + "px"
		e("viewContainer").style.left = (-1 * x + (VIEWPORT_WIDTH/2)) + "px"
	}
	// Left edge
	else if (x - VIEWPORT_WIDTH/2 <= 0) {
		//log("Min horizontal contstraint violated for viewport.");
		e("viewport").style.left = 0 + "px";
	}
	// Right edge
	else {
		//log("Max horizontal contstraint violated for viewport.");
		e("viewport").style.left = (IMAGE_WIDTH - (VIEWPORT_WIDTH) - 2*VIEWPORT_BORDER) + "px"
		e("viewContainer").style.left = (-1 * (IMAGE_WIDTH - (VIEWPORT_WIDTH) - 2*VIEWPORT_BORDER)) + "px"
	}

	// Normal case, not touching border
	if ((y + e("viewport").offsetHeight - VIEWPORT_HEIGHT/2 - 2*VIEWPORT_BORDER) < IMAGE_HEIGHT) {
		
		// Top edge
		if (y < (VIEWPORT_HEIGHT/2 + VIEWPORT_BORDER)) {
			e("viewport").style.top = 0 + "px"
		}
		else {
			e("viewport").style.top = (y - (VIEWPORT_HEIGHT/2) - VIEWPORT_BORDER) + "px"
			e("viewContainer").style.top = (-1 * y + (VIEWPORT_HEIGHT/2)) + "px"
		}
	}
	// Bottom edge
	else {
		//log("Vertical contstraint violated for viewport.");
		e("viewport").style.top = (IMAGE_HEIGHT - (VIEWPORT_HEIGHT) - 2*VIEWPORT_BORDER) + "px"
		e("viewContainer").style.top = (-1 * (IMAGE_HEIGHT - (VIEWPORT_HEIGHT) - 2*VIEWPORT_BORDER)) + "px"
	}
}

function setViewportTag(x, y) {
	// Position the viewport tag below and to the right of the viewport based on
	// the width of the viewport and the mouse offset, take borders into account as well.
	// Finally, add a 1px spacer from the viewport

	// Account for the tag being close to the edge of the image and constrain it to
	// stay within the container.

	// Method 0: No edge detection:
	/*
	e("viewportTag").style.left = (tileX + VIEWPORT_WIDTH/2 + 1) + "px";
	e("viewportTag").style.top = (tileY + VIEWPORT_HEIGHT/2 + 1) + "px";
	*/

	// Method 1: Follow edges except for bottom right corner where the tag would go off
	// both bottom and right sides - in that case flip it horizontally:

	if ((x + VIEWPORT_WIDTH/2 + e("viewportTag").offsetWidth) < IMAGE_WIDTH) {
		if (x < VIEWPORT_WIDTH/2 + VIEWPORT_BORDER) {
			e("viewportTag").style.left = (VIEWPORT_WIDTH + 2*VIEWPORT_BORDER) + "px";
		}
		else {
			e("viewportTag").style.left = (x + VIEWPORT_WIDTH/2 + VIEWPORT_BORDER) + "px";
		}
	}
	else {
		if ((y + VIEWPORT_HEIGHT/2 + e("viewportTag").offsetHeight) < IMAGE_HEIGHT) {
			e("viewportTag").style.left = (IMAGE_WIDTH - e("viewportTag").offsetWidth) + "px";
		}
		else {
			if ((x + VIEWPORT_WIDTH/2) < IMAGE_WIDTH) {
				e("viewportTag").style.left = (x - VIEWPORT_BORDER - VIEWPORT_WIDTH/2 - e("viewportTag").offsetWidth) + "px";
			}
			else {
				e("viewportTag").style.left = (IMAGE_WIDTH - e("viewportTag").offsetWidth - e("viewport").offsetWidth) + "px";
			}
			//log("Both horizontal and vertical constraints violated for viewport tag.");
		}
		//log("Horizontal constraint violated for viewport tag.");
	}

	if ((y + VIEWPORT_HEIGHT/2 + e("viewportTag").offsetHeight) < IMAGE_HEIGHT) {
	
		if (y < VIEWPORT_HEIGHT/2 + VIEWPORT_BORDER) {
			e("viewportTag").style.top = (VIEWPORT_HEIGHT + 2*VIEWPORT_BORDER) + "px";
		}
		else {
			e("viewportTag").style.top = (y + VIEWPORT_HEIGHT/2 + VIEWPORT_BORDER) + "px";
		}
	}
	else {
		//log("Vertical constraint violated for viewport tag.");
		e("viewportTag").style.top = (IMAGE_HEIGHT - e("viewportTag").offsetHeight) + "px";
	}

	// Method 2: Flip tag horizontally as soon as it reaches the right side of the image container:
	/*
	if ((x + VIEWPORT_WIDTH/2 + e("viewportTag").offsetWidth) < IMAGE_WIDTH) {
		e("viewportTag").style.left = (x + VIEWPORT_WIDTH/2 + VIEWPORT_BORDER) + "px";
	}
	else {
		//log("Horizontal constraint violated for viewport tag.");
		e("viewportTag").style.left = (x - VIEWPORT_WIDTH/2 - VIEWPORT_BORDER - e("viewportTag").offsetWidth) + "px";
	}

	if ((y + VIEWPORT_HEIGHT/2 + e("viewportTag").offsetHeight) < IMAGE_HEIGHT) {
		e("viewportTag").style.top = (y + VIEWPORT_HEIGHT/2 + VIEWPORT_BORDER) + "px";
	}
	else {
		//log("Vertical constraint violated for viewport tag.");
		e("viewportTag").style.top = (IMAGE_HEIGHT - e("viewportTag").offsetHeight) + "px";
	}
	*/

	// Method 3: Flip tag vertically as soon as it reaches the bottom of the image container:
	/*
	if ((x + VIEWPORT_WIDTH/2 + e("viewportTag").offsetWidth) < IMAGE_WIDTH) {
		e("viewportTag").style.left = (x + VIEWPORT_WIDTH/2 + VIEWPORT_BORDER) + "px";
	}
	else {
		//log("Horizontal constraint violated for viewport tag.");
	}

	if ((y + VIEWPORT_HEIGHT/2 + e("viewportTag").offsetHeight) < IMAGE_HEIGHT) {
		e("viewportTag").style.top = (y + VIEWPORT_HEIGHT/2 + VIEWPORT_BORDER) + "px";
	}
	else {
		//log("Vertical constraint violated for viewport tag.");
		e("viewportTag").style.top = (y - VIEWPORT_HEIGHT/2 - VIEWPORT_BORDER - e("viewportTag").offsetHeight) + "px";
	}
	*/
	// Method 4: Flip tag both horizontally and vertically as soon as it reaches the edges of the image container:
	/*
	if ((x + VIEWPORT_WIDTH/2 + e("viewportTag").offsetWidth) < IMAGE_WIDTH) {
		e("viewportTag").style.left = (x + VIEWPORT_WIDTH/2 + VIEWPORT_BORDER) + "px";
	}
	else {
		//log("Horizontal constraint violated for viewport tag.");
		e("viewportTag").style.left = (x - VIEWPORT_WIDTH/2 - VIEWPORT_BORDER - e("viewportTag").offsetWidth) + "px";
	}

	if ((y + VIEWPORT_HEIGHT/2 + e("viewportTag").offsetHeight) < IMAGE_HEIGHT) {
		e("viewportTag").style.top = (y + VIEWPORT_HEIGHT/2 + VIEWPORT_BORDER) + "px";
	}
	else {
		//log("Vertical constraint violated for viewport tag.");
		e("viewportTag").style.top = (y - VIEWPORT_HEIGHT/2 - VIEWPORT_BORDER - e("viewportTag").offsetHeight) + "px";
	}
	*/
}

function hideViewport() {
	e("viewport").style.display = "none";
	e("viewportTag").style.display = "none";
}

function setZoomWindow() {

	var zs = document.getElementById("zoomSelect");

	var size = zs.options[zs.selectedIndex].value;

	//log("Changing zoom window to size: " + size);

	VIEWPORT_SIZE = size;
	initZoomWindow();
}

function viewportMove(evt) {

	//log("Mouse move!");

	//var tileX;
	//var tileY;

	//log(typeof(evt));

	// Firefox is passed the cursor position relative to the page in the pageX and pageY variables,
	// since we're using a margin on the 1x magnification tile container, we'll use these coords and offset by the container margin.
	if (evt.pageX) {

		//var yOffset = e("headerContainer").offsetHeight;

		setViewport(evt.pageX - CONTAINER_MARGIN_X, evt.pageY - CONTAINER_MARGIN_Y);
		setViewportTag(evt.pageX - CONTAINER_MARGIN_X, evt.pageY - CONTAINER_MARGIN_Y);

		// Arbitrary adjustments here based on observation.
		//log(": (" + evt.pageX + ", " + evt.pageY + ")");

		tileX = evt.pageX - CONTAINER_MARGIN_X;
		tileY = evt.pageY - CONTAINER_MARGIN_Y;
		//setViewport(tileX, tileY);
		//setViewportTag(tileX, tileY);
		//log("(" + tileX + ", " + tileY + ")");
	}

	// IE7 is passed the container coords in the x and y variables, but pageX and pageY are undefined,
	// so we can use the x/y without margin offsets.
	else if (evt.x) {
	//else if (evt.screenX) {
		// IE viewport problem introduced by divs with absolute positioning...set to relative to fix.
		//log("(" + evt.x + ", " + evt.y + ")");

		setViewport(evt.x, evt.y);
		setViewportTag(evt.x, evt.y);

		//tileX = evt.x - CONTAINER_MARGIN_X;
		//tileY = evt.y - CONTAINER_MARGIN_Y;
		//setViewport(tileX, tileY);
		//setViewportTag(tileX, tileY);
		//log("(" + tileX + ", " + tileY + ")");
	}

}

function viewportOn(evt) {
	//log(typeof(evt));

	// Event handling code, if needed.
	/*
	var tileX;
	var tileY;

	//log(typeof(evt));

	// Firefox is passed the cursor position relative to the page in the pageX and pageY variables,
	// since we're using a margin on the 1x magnification tile container, we'll use these coords and offset by the container margin.
	if (evt.pageX) {


		tileX = evt.pageX;
		tileY = evt.pageY;

		//log("(" + evt.pageX + ", " + evt.pageY + ")");
	}

	// IE7 is passed the container coords in the x and y variables, but pageX and pageY are undefined,
	// so we can use the x/y without margin offsets.
	else {
		tileX = evt.x - 2;
		tileY = evt.y - 2;

		//log("(" + evt.x + ", " + evt.y + ")");
	}

	log("(" + tileX + ", " + tileY + ")");

	setViewport(tileX, tileY);
	*/

	e("viewport").style.display = "block";
	e("viewportTag").style.display = "block";
	/*
	log("Mouse on!");
	*/
}

function viewportOff(evt) {
	//log(typeof(evt));

	// This clause is required only here (not in _move or _on) since the modal divs made
	// visible during the entry process come between the tileContainer and the mouse, which
	// is viewed as a mouseOut event and will cause the frame and input to disappear.
	if (entryMode == true) {
		return;
	}

	// Detect whether we're at the edges or not to enable the submission sample mouseovers
	// without tearing down the viewport and tag.
	//if (evt.pageX < IMAGE_WIDTH && evt.pageX > 0 && evt.pageY < IMAGE_HEIGHT && evt.pageY > 0) {
	if (evt.pageX < IMAGE_WIDTH + CONTAINER_MARGIN_X &&  evt.pageY < IMAGE_HEIGHT + CONTAINER_MARGIN_Y) {
		//log("(" + evt.pageX + ", " + evt.pageY + ")");
		//log("Found a submissionHandler border.");
		return;

	}

	else if ((evt.x-2) < IMAGE_WIDTH && (evt.y-2) < IMAGE_HEIGHT) {
		//log("(" + evt.x + ", " + evt.y + ")");
		//log("Found a submissionHandler border.");
		return;

	}

	hideViewport();
	//log("Mouse out!");
}

// Simply pass through the onmousemove event to the viewport mouse event handler
function sampleMove(evt) {
	//viewportMove(evt);
	if (evt.pageX) {
		viewportMove(evt);
	}

	else if (evt.x) {

		setViewport(evt.x - CONTAINER_MARGIN_X, evt.y - CONTAINER_MARGIN_Y);
		setViewportTag(evt.x - CONTAINER_MARGIN_X, evt.y - CONTAINER_MARGIN_Y);

	}
	
}

function sampleOn(evt, id) {
	showSampleTag(id.split("_")[1]);
}

function sampleOff(evt) {
	initClickTag();
}

// Responsible for changing the click tag to show the contents of the sample submissions
// On the onmouseover event, this method is passed the integer id of the sample mouse event handler,
// which it can use to get/set the info it needs.
// On the onmouseout event, it is passed null, which resets the tag to its default state.

function showSampleTag(id) {
	e("viewportTag").style.backgroundColor = "#5A5A5A";
	//e("viewportTag").style.height = "25px";
	// Get the innerHTML of the submission sample to display in the clickTag
	//e("clickTag").innerHTML = "Submission #: " + e("sampleText_" + id).innerHTML;
	setClickTag("Submission #: " + e("sampleText_" + id).innerHTML);

	// Must set both viewport and clickTag width, IE6 won't size correctly if they aren't both set.

	// Sizing was chosen based on 66px for the text 'Submission #: ', plus 6px for each digit of the submssion id,
	// plus 4px (right margin) for the clickTag, or 7px for the viewport.

	//log("Sample text length: " + e("sampleText_" + id).innerHTML.length);

	//e("clickTag").style.width = 78 + 6*e("sampleText_" + id).innerHTML.length + 11 + "px";
	e("viewportTag").style.width = 100 + 8*e("sampleText_" + id).innerHTML.length + "px";

	//log(sid + ", " + e(sid).innerHTML.length);
}

function initClickTag() {
	e("viewportTag").style.backgroundColor = "#797979";
	e("viewportTag").style.width = "170px";
	//e("viewportTag").style.height = "75px";
	
	if (!HAS_SUBMITTED_PIXEL) {
		//e("clickTag").innerHTML = 
		//setClickTag("<span class='white'>Click </span><span class='black'>a dark area to reveal the image.</span>");
		//setClickTag("<span class='black'>Click a dark area </span><span class='white'>to see your contribution to freeing the airwaves and look through our looking glass.</span>");
		
		var tagText = "<span class='black'><span class='white'>Thank you. </span>Click a dark area to show how you've helped to open up the skies.</span>";
		//tagText += "<p style='padding:5px 0 0 0;'><span class='white'>Click a dark area </span>to see through our looking glass.</span></p>"
		setClickTag(tagText);
		
	}
	else {
		//e("clickTag").innerHTML = "<span class='white'>Thank you </span><span class='black'>for your support.</span>";
		//setClickTag("<span class='white'>Thank you </span><span class='black'>for doing your part to free the airwaves.</span>");
		//var tagText = "<span class='white'>Thank you </span><span class='black'>for doing your part to free the airwaves.</span>";
		var tagText = "Click again to <span class='white'>tell a friend </span><span class='black'>to help free the airwaves.</span>";
		setClickTag(tagText);
	}
}

function setClickTag(message) {
	e("clickTag").innerHTML = message;
}

function toggleMode() {
	if (entryMode == false) {
		entryMode = true;
		//e("entryMask").style.display = "block";
		//e("viewportTag").style.zIndex = 20;
	}
	else {
		entryMode = false;
		//e("entryMask").style.display = "none";

		// Re-initialize the zoom window, as the mouse position will have changed and
		// the first mouse move will thrash it directly from one position to another.

		// BLAST! Doesn't reposition until it gets an event.
		//initZoomWindow();
		//e("clickTag").style.display = "block";
		//e("entryTag").style.display = "none";
		//e("completeTag").style.display = "none";
		//e("viewportTag").style.width = "170px";
		//e("viewportTag").style.height = "75px";
		//e("viewportTag").style.zIndex = 15;
	}
	//log("entryMode: " + entryMode);
}

function pixelClick(evt) {
	if (entryMode) {
		return;
	}
	
	if (HAS_SUBMITTED_PIXEL) {
		window.location.href="index.html";
		return;
	}

	// Click coords, to be set below, see comments.
	var clickX = null;
	var clickY = null;

	// Tile coords, to be set after click coords are determined below.
	//var tileX = null;
	//var tiley = null;

	// Firefox is passed the cursor position relative to the page in the pageX and pageY variables,
	// since we have no margin on the tileContainer and it's top/left origins are at (0,0), we can use these exact values.
	if (evt.pageX) {
		//log("Click at: (" + evt.pageX + ", " + evt.pageY + ")");

		clickX = evt.pageX - CONTAINER_MARGIN_X;
		clickY = evt.pageY - CONTAINER_MARGIN_Y;
	}

	// IE6/7 is passed the container coords in the x and y variables, but pageX and pageY are undefined,
	// so we'll use the x/y variables.
	else {
		//log("Click at (" + evt.x + ", " + evt.y + ")");

		// With the current tile/container setup, IE seems to be offset 2px top and left, adjust here.
		//clickX = evt.x - 2;
		//clickY = evt.y - 2;
		clickX = evt.x;
		clickY = evt.y;
	}


	// Click values start at 0, so for a tile size of 128, x=0 to x=127 resolve to tile x=0, x=128 resolves to tile x=1,
	// giving 128px per tile as intended.
	//tileX = Math.floor(clickX/TILE_WIDTH);
	//tileY = Math.floor(clickY/TILE_WIDTH);

	// Set hidden fields for now
	e("click_x").value = clickX;
	e("click_y").value = clickY;

	//log("Stored: " + e("click_x").value + ", " + e("click_y").value);

	// Branch to workflow if they've filled out the module form
	
	/*
	if (HAS_SUBMITTED_MOD) {
		first_name = document.getElementById ("first_name").value;
		last_name = document.getElementById ("last_name").value;
		zip = document.getElementById ("zip").value;
		email = document.getElementById ("email").value;
		keep_me_updated = document.getElementById ("keep_me_updated").checked;

		if (keep_me_updated == true) {
			keep_me_updated = 1; 
		}
		else {
			keep_me_updated = 0;
		}
		
		fta_ws.click (clickX, clickY, first_name, last_name, email, zip, "US", keep_me_updated);
		toggleMode();
		return;		
	}
	*/
	
	toggleMode();
	//showNotification("Submitting your request...");
	
	// Bring up the submission entry dialog, pass in x/y to detect edges
	//showEntryDialog(clickX, clickY);
	fta_ws.click (clickX, clickY, reveal_firstName, reveal_lastName, reveal_email, reveal_zip, "US", reveal_keepMeUpdated);

	//log("Click at: (" + clickX + ", " + clickY + ") - resolves to tile: " + tileY + ", " + tileX);

	// Click position relative to the top left corner of the tile.
	//log("Tile coords: (" + (clickX - (tileX*TILE_WIDTH)) + ", " + (clickY - (tileY*TILE_HEIGHT)) + ")");

	// Get the tile by id.
	//var tile = e(tileY + "_" + tileX);
}

function sampleClick(evt, id) {
	//log("Submission " + id + " clicked.");
}

/*
function showMenuItem(menuItem) {

	// Hide the magnification frame and position it offscreen, there are some strange behaviors when
	// it's in the tile container and not hidden when the modal dialog appears.

	var v = e("viewport");
	v.style.display = "none";

	var vt = e("viewportTag");
	vt.style.display = "none";

	hideMenuItems();
	showModalContainer();
	e(menuItem).style.display = "block";
	//e(menuItem + "Link").style.borderBottom = "1px solid #FFF";
	//e(menuItem + "Block").style.display = "block";
}
*/

/*
function hideMenuItems() {
	//e("about").style.display = "none";
	//e("aboutLink").style.borderBottom = "1px solid #000";
	//e("aboutBlock").style.display = "none";
	//e("video").style.display = "none";
	//e("videoLink").style.borderBottom = "1px solid #000";
	//e("videoBlock").style.display = "none";
	e("takeAction").style.display = "none";
	//e("takeActionLink").style.borderBottom = "1px solid #000";

	//e("takeActionBlock").style.display = "none";
}
*/

function showModalContainer() {
	e("modalContainer").style.display = "block";
	e("dialogContainer").style.display = "block";
}

function hideModalContainer() {
	e("modalContainer").style.display = "none";
	e("dialogContainer").style.display = "none";
}

function closeMenu() {
	//hideMenuItems();
	hideModalContainer();
}

function showEntryDialog(x, y) {

	e("clickTag").style.display = "none";
	e("viewportTag").style.width = ENTRY_TAG_WIDTH + "px";
	e("viewportTag").style.height = ENTRY_TAG_HEIGHT + "px";
	e("entryTag").style.display = "block";

	// Invoked when viewport is too close to right edge
	// Take viewportTag border into account
	if ((x + VIEWPORT_WIDTH/2 + ENTRY_TAG_WIDTH + 2*VIEWPORT_BORDER) >= IMAGE_WIDTH) {

		// Invoked when viewport is too close to right edge and bottom edge
		if ((y + VIEWPORT_HEIGHT/2 + ENTRY_TAG_HEIGHT + 2*VIEWPORT_BORDER) >= IMAGE_HEIGHT) {
			//log("Entry dialog violated horizontal AND vertical constraint...");

			// Take into account the mouse being very close to the screen edge, at that point,
			// the viewportTag is not following it, but we still have to handle the x position
			if (x + VIEWPORT_WIDTH/2 < IMAGE_WIDTH) {
				e("viewportTag").style.left = (x - VIEWPORT_WIDTH/2 - VIEWPORT_BORDER - ENTRY_TAG_WIDTH - 2*VIEWPORT_TAG_BORDER) + "px";
			}
			else {
				e("viewportTag").style.left = (IMAGE_WIDTH - ENTRY_TAG_WIDTH - VIEWPORT_WIDTH - 2*VIEWPORT_TAG_BORDER - 2*VIEWPORT_BORDER) + "px";
			}

			e("viewportTag").style.top = (IMAGE_HEIGHT - ENTRY_TAG_HEIGHT - 2*VIEWPORT_BORDER) + "px";
		}

		else {
			//log("Entry dialog violated only horizontal constraint...");
			e("viewportTag").style.left = (IMAGE_WIDTH - ENTRY_TAG_WIDTH - 2*VIEWPORT_BORDER) + "px";
		}
	}

	// Invoked when viewport is too close to bottom edge
	else if ((y + VIEWPORT_HEIGHT/2 + ENTRY_TAG_HEIGHT + 2*VIEWPORT_BORDER) >= IMAGE_HEIGHT) {
		//log("Entry dialog violated only vertical constraint...");
		e("viewportTag").style.top = (IMAGE_HEIGHT- ENTRY_TAG_HEIGHT - 2*VIEWPORT_BORDER) + "px";
	}


}

function showCompleteDialog() {
	e("entryTag").style.display = "none";
	e("completeTag").style.display = "block";
}

function resetFCCText() {
	e("takeActionTitle").innerHTML = "Take action.";
	e("takeActionSkip").style.visibility = "hidden";
	showNotification("Thank you for your support, please check back often to see the progress!");
	setTimeout("hideNotification()", 5000);
}

/*
function closeCompleteTag() {
	toggleMode();
}
*/

function setOpacity(object, value) {

	if (typeof(object) == "object") {
		//log("Setting " + object.id + "'s [" + typeof(object) + "] opacity to " + value);
	}
	else if (typeof(object) == "string"){
		//log("Setting " + object + "'s [" + typeof(object) + "] opacity to " + value);
		object = document.getElementById(object);
	}
	object.style.opacity = value/10;
	object.style.filter = 'alpha(opacity=' + value*10 + ')';
}

// Create a sample point with text
function createSample(sampleId, submissionId, x, y, size) {

	var div = e("sample_" + sampleId);

	div.innerHTML = "";

	var tileX = Math.floor(x/size) * size;
	var tileY = Math.floor(y/size) * size;

	div.style.left = tileX + "px";

	if (size == 16) {
		// Looks good for 16
		div.style.top = (tileY+2) + "px";
	}

	if (size == 8) {
		// Looks good for 8
		div.style.top = (tileY - (size/2) + 1) + "px";
	}

	if (size == 4) {
		// Looks good for 4
		div.style.top = (tileY - 6) + "px";
	}
	if (size == 2) {
		// Looks good for 2
		div.style.top = (tileY - 7) + "px";
	}

	//div.style.width = (REVEAL_SIZE_PX - 2*VIEWPORT_BORDER) + "px";
	//div.style.height = (REVEAL_SIZE_PX -2*VIEWPORT_BORDER) + "px";
	//div.style.width = (size - 2*VIEWPORT_BORDER) + "px";
	//div.style.height = (size -2*VIEWPORT_BORDER) + "px";
	//div.style.display = "block";

	//div.style.opacity = (10 - sampleId)/10;
	//div.style.filter = 'alpha(opacity=' + ((10 - sampleId)*10) + ')';
	//div.setAttribute("opacity", (10-sampleId)/10);
	//div.setAttribute("filter", "alpha(opacity=" + ((10 - sampleId)*10) + ")");


	var para = document.createElement("p")
	//var para = e("sampleText_" + sampleId);
	para.setAttribute("id", "sampleText_" + sampleId);
	para.style.paddingLeft = (size+2) + "px";

	//para.setAttribute("opacity", (10-sampleId)/10);
	//para.setAttribute("filter", "alpha(opacity=" + ((10 - sampleId)*10) + ")");
	//para.style.opacity = (10 - sampleId)/10;
	//para.style.filter = 'alpha(opacity=' + ((10 - sampleId)*10) + ')';


	//Opacity example
	//filter:alpha(opacity=0);
	//opacity:0.0;
	para.appendChild(document.createTextNode(submissionId));

	div.appendChild(para);
	setOpacity(div, (10-sampleId));

	//setHandler(sampleId, x, y, size);
}


function setHandler(id, x, y, size) {
	//log("Setting handler for sample " + id + " at (" + x + ", " + y + "), size " + size);

	var sid = "sampleHandler_" + id;

	// Firefox was not cooperating with passing parameters to functions set
	// directly through the DOM, it couldn't find the 'event' parameter at runtime.
	// Hardcoded each submissionHandler in the HTML in classic brute force fashion.
	/*
	var para = document.createElement("p");
	para.className = "submissionHandler";
	para.setAttribute("id", "sampleHandler_" + id);

	para.onclick = function() {
		submissionClick();
	};

	para.onmouseover = function() {
		viewportOn(this);
	};

	para.onmousemove = function() {
		viewportMove(event);
	};


	para.style.left = (x - 1) + "px";
	para.style.top = (y - 1) + "px";

	para.style.width = 10 + 7*(e("sample_" + id).innerHTML.length - 7) + "px";

	e("eventContainer").appendChild(para);
	*/

	var tileX = Math.floor(x/size) * size;
	var tileY = Math.floor(y/size) * size;

	e(sid).style.left = tileX + "px";
	e(sid).style.top = tileY + "px";
	e(sid).style.width = size + "px";
	e(sid).style.height = size + "px";

	//log("innerHTML length: " + e("sample_" + id).innerHTML.length);
	// For some strange reason, the innerHTML returned has a length of 7 plus whatever
	// text is actually in there, take that into account here, multiply that length by
	// arbitrary value of 7.
	//e(sid).style.width = 10 + 7*(e("sample_" + id).innerHTML.length - 7) + "px";
}

function setChangedField() {
	if (e("fcc_changed").value == "1") {
		return;
	}
	else {
		//log("Setting FCC changed flag.");
		e("fcc_changed").value = "1";
	}

}

function showNotification(message) {
	e("notificationContainer").style.display = "block";
	e("notificationText").innerHTML = message;
}

function hideNotification() {
	e("notificationContainer").style.display = "none";
	e("notificationText").innerHTML = "";
}

function lowerOpacity() {

	e("fadeContainer").style.display = "block";

	if (OPACITY == 0) {
		OPACITY = 10;
	}
	else {
		//--OPACITY;
		OPACITY -= 0.5;
	}

	document.getElementById("fadeContainer").style.opacity = OPACITY/10;
	document.getElementById("fadeContainer").style.filter = 'alpha(opacity=' + OPACITY*10 + ')';

}

function raiseOpacity() {

	e("fadeContainer").style.display = "block";

	if (OPACITY == 10) {
		OPACITY = 0;
	}
	else {
		//++OPACITY;
		OPACITY += 0.5;
	}

	document.getElementById("fadeContainer").style.opacity = OPACITY/10;
	document.getElementById("fadeContainer").style.filter = 'alpha(opacity=' + OPACITY*10 + ')';

}


function fadeOut() {
	var delay = 0;

	for (var i=0; i<10-OPACITY; ++i) {
		/*
		if (OPACITY == 10) {
			return;
		}
		*/
		setTimeout("raiseOpacity()", delay)
		delay += QUANTUM;
	}

}

/*
function fadeIn(div, steps, start, end) {

	log("Fading " + div + " from " + start + " to " + end + " over " + steps + " steps.");

	if (steps <= 0) {
		return;
	}

	var delay = 0;
	
	var delta = start - end;
	var fadeAmount = delta/steps;
	var currentFade = start - fadeAmount;
	
	for (var i=0; i<steps; i++) {
		setTimeout("setOpacity('" + div + "', " + currentFade + ")", delay);
		//setTimeout("setOpacity('revealContainer', " + currentFade/10 + ")", delay);
		currentFade -= fadeAmount;
		delay += QUANTUM;
	}
}
*/

function fadeIn() {
	var delay = 0;

	//for (var i=10; i>10-OPACITY; --i) {
	for (var i=20; i>0; --i) {
		setTimeout("lowerOpacity()", delay)
		delay += QUANTUM;
	}

	setTimeout("hideFadeContainer()", delay);
}

function hideFadeContainer() {
	e("fadeContainer").style.display = "none";
	//e("sampleContainer").style.overflow = "visible";
	//e("logoContainer").style.zIndex = 20;
}

function moduleClick() {

	var alertString = "";
	
	var		first_name = document.getElementById ("mod_first_name").value;
	if (first_name == "" || first_name == null) {
		alertString += "first name\n";
	}
	
	var		last_name = document.getElementById ("mod_last_name").value;
	if (last_name == "" || last_name == null) {
		alertString += "last name\n";
	}
	
	var		email = document.getElementById ("mod_email").value;
	if (email == "" || email == null) {
		alertString += "email\n";
	}

	if (!isValidEmail(email)) {
		alertString = "please enter a valid email address.\n";
		alert(alertString);
		return;
	}

	var		zip = document.getElementById ("mod_zip").value;
	if (zip == "" || zip == null) {
		alertString += "zip/country code\n";
	}
	if (zip.length > 10) {
		alertString = "zip/country code must be less than 10 characters.\n";
		alert(alertString);
		return;
	}
	
	if (alertString != "") {
		alertString = "Please complete the following fields before submitting:\n" + alertString;
		alert(alertString);
		return;
	}

	if (!fta_captcha.isValid()) {
		alert("Please ensure that the text matches the security word.");
		return;
	}

	var		keep_me_updated = document.getElementById ("mod_keep_me_updated").checked;

	if (keep_me_updated == true) {
		keep_me_updated = 1; 
	}
	else {
		keep_me_updated = 0;
	}

	document.getElementById ("first_name").value = document.getElementById ("mod_first_name").value;
	document.getElementById ("last_name").value = document.getElementById ("mod_last_name").value;
	document.getElementById ("zip").value = document.getElementById ("mod_zip").value;
	document.getElementById ("email").value = document.getElementById ("mod_email").value;
	document.getElementById ("keep_me_updated").checked = document.getElementById ("mod_keep_me_updated").checked;
	document.getElementById ("captchaInput").value = document.getElementById ("mod_captchaInput").value;
	
	HAS_SUBMITTED_MOD = true;
	setClickTag("<span class='white'>Click </span><span class='black'>on a dark area to reveal the image</span>");
	window.scroll(0, CONTAINER_MARGIN_Y + 10);
}

function toggleContent() {
	var c = e("container");
	var fc = e("fadeContainer");
	
	if (c.style.display == "block") {
		c.style.display = "none";
		fc.style.display = "none";
	}
	
	else {
		c.style.display = "block";
		fc.style.display = "block";
	}
}

function startRevealApp() {
	
	e("fcc_state").style.display = "none";
	e("fccTextArea").style.display = "none";
	e("revealContainer").style.display = "block";
	initClickTag();
	refreshTiles();
	
	setTimeout("getLast10();", 1000);
	setTimeout("fadeIn();", 3000);
}

function updateSig() {
	try {
		if (document.getElementById("fcc_first_name").value != "") {
			document.getElementById("dynamicName").innerHTML = document.getElementById("fcc_first_name").value + " " + document.getElementById("fcc_last_name").value;
		}
		
		if (document.getElementById("fcc_address1").value != "") {
			document.getElementById("dynamicAddress").innerHTML = document.getElementById("fcc_address1").value;
		}
		if (document.getElementById("fcc_address2").value != "") {
			document.getElementById("dynamicAddress").innerHTML = document.getElementById("fcc_address1").value + ", " + document.getElementById("fcc_address2").value;		
		}
	
		var selectedCity = "";
	
		if (document.getElementById("fcc_city").value != "") {
			selectedCity = document.getElementById("fcc_city").value;
			document.getElementById("dynamicLoc").innerHTML = selectedCity;
		}
	
		var selectedState = "";
		var	state = document.getElementById ("fcc_state");
		if (state.selectedIndex != 0) {
			selectedState = state.options[state.selectedIndex].value;
			document.getElementById("dynamicLoc").innerHTML = selectedCity + ", " + selectedState;
		}
		
		if (document.getElementById("fcc_zip").value != "") {
			document.getElementById("dynamicLoc").innerHTML = selectedCity + ", " + selectedState + " " + document.getElementById("fcc_zip").value;
		}
	}
	catch (e) {
		alert("updateField threw an exception: " + e);
	}
}

function flagFCCInputLabel(id) {
	try {
		document.getElementById(id).style.color = "#F00";
	}
	catch (e) {
		alert("flagFCCInputLabel threw an exception for id: " + id + ": " + e);
	}
}

function clearFCCInputLabel(id) {
	try {
		document.getElementById(id).style.color = "#000";
	}
	catch (e) {
		alert("clearFCCInputLabel threw an exception for id: " + id + ": " + e);
	}
}

function resetFCCInputLabels() {
	try {
		document.getElementById("fcc_first_name_label").style.color = "#000";
		document.getElementById("fcc_last_name_label").style.color = "#000";
		document.getElementById("fcc_email_label").style.color = "#000";
		document.getElementById("fcc_city_label").style.color = "#000";
		document.getElementById("fcc_state_label").style.color = "#000";
		document.getElementById("fcc_zip_label").style.color = "#000";
	}
	catch (e) {
		alert("resetFCCInputLabels threw an exception: " + e);
	}
}

function clearFCCInputFields() {
	try {
		document.getElementById("fcc_first_name").value = "";
		document.getElementById("fcc_last_name").value = "";
		document.getElementById("fcc_email").value = "";
		document.getElementById("fcc_address1").value = "";
		document.getElementById("fcc_address2").value = "";
		document.getElementById("fcc_city").value = "";
		document.getElementById("fcc_state").selectedIndex = 0;
		document.getElementById("fcc_zip").value = "";
		document.getElementById("fcc_keep_me_updated").checked = false;
	}
	catch (e) {
		alert("clearFCCInputFields threw an exception: " + e);
	}
}